package com.css.fxfzysx.modules.specialMapAnalysis.service.impl;

import com.css.fxfzysx.modules.lifeline.entity.BridgeEntity;
import com.css.fxfzysx.modules.lifeline.entity.DxPipeNetworkEntity;
import com.css.fxfzysx.modules.lifeline.entity.RoadEntity;
import com.css.fxfzysx.modules.specialMapAnalysis.repository.SpecialRepository;
import com.css.fxfzysx.modules.specialMapAnalysis.service.SpecialService;
import com.css.fxfzysx.modules.specialMapAnalysis.vo.ResultVo;
import com.css.fxfzysx.util.PlatformObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class SpecialServiceImpl implements SpecialService {

    @Autowired
    SpecialRepository specialRepository;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public Map specialMapAnalysis(String type, String intensity) {
        //type   地下管网:1,桥梁:5,道路:6
        Map<String, Object> map = new HashMap<>();
        for(String type2 : type.split(",")){
            switch (type2) {
                case "1":
                    map.put("dxPipeNetwork",dxPipeNetworkData(intensity));
                case "5":
                    map.put("bridge",bridgeData(intensity));
                /*case "6":
                    map.put("road",roadData(intensity));*/
            }
        }
        return map;
    }

    //道路
    private Map<String, Object> roadData(String intensity) {
        Map<String, Object> map = new HashMap<>();
        List<String> list = new ArrayList<>();
        //获取 破坏程度 设防程度  年份  占比
        String dIntensity = convertIntensity(intensity);//转换设防烈度格式
        List<ResultVo> resList = specialRepository.mtolProjectRoadData(dIntensity);
        for(ResultVo resultVo : resList){
            String fortification = resultVo.getFortification();
            String intensity1 = convertIntensity2(fortification);//转换设防烈度格式
            List<RoadEntity> rList = specialRepository.roadData(intensity1);//筛选道路所有数据
            for(RoadEntity roadEntity : rList){
                String fortification1 = roadEntity.getFortification();
                if(list.contains(fortification1)){
                    continue;
                }
                if(intensity1.equals(fortification1)){
                    boolean res = specialRepository.updateRoadDamageExtentByIntensity(resultVo.getBreakState(), intensity1);
                    if(res){
                        map.put(intensity1,resultVo.getBreakState());
                    }
                }
                list.add(intensity1);
            }
        }
        return map;
    }


    //桥梁-线
    private Map<String, Object> bridgeData(String intensity) {
        Map<String, Object> map = new HashMap<>();
        List<String> list = new ArrayList<>();
        //获取 破坏程度 设防程度  年份  占比
        String dIntensity = convertIntensity2(intensity);//转换设防烈度格式
        List<ResultVo> resList = specialRepository.mtolProjectBridgeData(dIntensity);
        Map<String, Map<String, String>> data = getData(resList);
        for(String str : data.keySet()){
            String phcd = data.get(str).get("phcd");
            String years = str.split("_")[0];
            String fortification = str.split("_")[1];
            String intensity1 = convertIntensity2(fortification);//转换格式
            List<BridgeEntity> bList = specialRepository.bridgeLineData(intensity1);//筛选桥梁所有数据
            for(BridgeEntity bridgeEntity : bList){
                String year1 = bridgeEntity.getBuildYear();
                String intensity2 = bridgeEntity.getIntensity();
                if(list.contains(year1+"-"+intensity2)){
                    continue;
                }
                Integer year = Integer.valueOf(year1);
                if(years.contains("年以前")){
                    Integer integer = changeYears("1", years).get(0);
                    if(year <= integer){
                        boolean res = specialRepository.updateDxDamageExtentByIntensityAndYear(data.get(str).get("phcd"), intensity2, year1);
                        if(res){
                            map.put(year1+"-"+intensity2,phcd);
                        }
                    }
                }else if(years.contains("-")){
                    Integer before = changeYears("2", years).get(0);
                    Integer after = changeYears("2", years).get(1);
                    if(before <= year && year <= after){
                        boolean res = specialRepository.updateBridgeDamageExtentByIntensityAndYear(phcd, intensity2, year1);
                        if(res){
                            map.put(year1+"-"+intensity2,phcd);
                        }
                    }
                }
                list.add(year1+"-"+intensity2);
            }
        }
        return map;
    }

    //地下管网
    private Map<String,Object> dxPipeNetworkData(String intensity){
        Map<String, Object> map = new HashMap<>();
        List<String> list = new ArrayList<>();
        //获取 破坏程度 设防程度  年份  占比
        String dIntensity = convertIntensity2(intensity);//转换设防烈度格式
        List<ResultVo> resList = specialRepository.mtolProjectDxData(dIntensity);
        Map<String, Map<String, String>> data = getData(resList);
        for(String str : data.keySet()){
            String phcd = data.get(str).get("phcd");
            String years = str.split("_")[0];
            String fortification = str.split("_")[1];
            String intensity1 = convertIntensity2(fortification);//转换格式
            List<DxPipeNetworkEntity> dList = specialRepository.dxPipeNetworkData(intensity1);//筛选地下管网所有数据
            for(DxPipeNetworkEntity dxPipeNetworkEntity : dList){
                String year1 = dxPipeNetworkEntity.getYear();
                String intensity2 = dxPipeNetworkEntity.getIntensity();
                if(list.contains(year1+"-"+intensity2)){
                    continue;
                }
                Integer year = Integer.valueOf(year1);
                if(years.contains("年以前")){
                    Integer integer = changeYears("1", years).get(0);
                    if(year <= integer){
                        boolean res = specialRepository.updateDxDamageExtentByIntensityAndYear(data.get(str).get("phcd"), intensity2, year1);
                        if(res){
                            map.put(year1+"-"+intensity2,phcd);
                        }
                    }
                }else if(years.contains("-")){
                    Integer before = changeYears("2", years).get(0);
                    Integer after = changeYears("2", years).get(1);
                    if(before <= year && year <= after){
                        boolean res = specialRepository.updateDxDamageExtentByIntensityAndYear(phcd, intensity2, year1);
                        if(res){
                            map.put(year1+"-"+intensity2,phcd);
                        }
                    }
                }
                list.add(year1+"-"+intensity2);
            }
        }
        return map;
    }


    private Map<String, Map<String, String>> getData(List<ResultVo> resList){
        Map<String, Map<String, Map<String, Integer>>> yearSfldCountMap = new HashMap<>();
        for (ResultVo resVo : resList) {
            Map<String, Map<String, Integer>> sfldCountMap = yearSfldCountMap.computeIfAbsent(
                    resVo.getYears(), k -> new HashMap<>()
            );
            Map<String, Integer> countMap = sfldCountMap.computeIfAbsent(
                    resVo.getFortification(), k -> new HashMap<>()
            );
            countMap.put(resVo.getBreakState(), countMap.getOrDefault(resVo.getBreakState(), 0) + resVo.getCount());
        }

        Map<String, Map<String, String>> yearSfldPhcdMap = new HashMap<>();
        for (Map.Entry<String, Map<String, Map<String, Integer>>> yearEntry : yearSfldCountMap.entrySet()) {
            String year = yearEntry.getKey();
            for (Map.Entry<String, Map<String, Integer>> sfldEntry : yearEntry.getValue().entrySet()) {
                String sfld = sfldEntry.getKey();
                Map<String, Integer> countMap = sfldEntry.getValue();
                String maxPhcd = null;
                int maxCount = 0;
                for (Map.Entry<String, Integer> countEntry : countMap.entrySet()) {
                    String phcd = countEntry.getKey();
                    int count = countEntry.getValue();
                    if (count > maxCount || (count == maxCount && phcdLevel(phcd) > phcdLevel(maxPhcd))) {
                        maxPhcd = phcd;
                        maxCount = count;
                    }
                }
                Map<String, String> phcdMap = yearSfldPhcdMap.computeIfAbsent(year + "_" + sfld, k -> new HashMap<>());
                phcdMap.put("phcd", maxPhcd);
                //phcdMap.put("count", String.valueOf(maxCount));
            }
        }
        return yearSfldPhcdMap;
    }


    static int phcdLevel(String phcd) {
        switch (phcd) {
            case "严重破坏":
                return 4;
            case "中等破坏":
                return 3;
            case "轻微破坏":
                return 2;
            case "基本完好":
                return 1;
            default:
                return 0;
        }
    }


    private List<Integer> changeYears(String type, String years){
        List<Integer> list = new ArrayList<>();
        if(!PlatformObjectUtils.isEmpty(years)){
            if(type.equals("1")){//例如 2010年以前
                String substring = years.substring(0, 4);
                list.add(Integer.valueOf(substring));
            }else if(type.equals("2")){//例如 1978-1989年
                years = years.substring(0,years.length()-1);
                Integer before = Integer.valueOf(years.split("-")[0]);
                Integer after = Integer.valueOf(years.split("-")[1]);
                list.add(before);
                list.add(after);
            }
        }
        return list;
    }

    private String convertIntensity(String intensity) {
        switch (intensity) {
            case "0":
                return "未设防";
            case "6":
                return "6度";
            case "7":
                return "7度";
            case "8":
                return "8度";
            case "9":
                return "9度";
            default:
                return null;
        }
    }

    private String convertIntensity2(String intensity) {
        switch (intensity) {
            case "未设防":
                return "0";
            case "6度":
                return "6";
            case "7度":
                return "7";
            case "8度":
                return "8";
            case "9度":
                return "9";
            default:
                return null;
        }
    }


}
